1.方法思路:用深搜和后序遍历结合,遍历所有节点,记录最大高度。时间为O(n),空间为O(max)。(自创)
代码如下(未测试):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | int DFS_PostOrder(BiTree T){ if (!T) return 0; //树空,高度为0 InitStack(S); BiTree *p=T,*r=NULL; //r为后序遍历时的辅助指针 int num=0,max=0; //num用来跟随程序实时记录层数,max用来记录最大值 while (p||!isEmpty(S)){ //以下为后序遍历略作修改 while (p){ //该结点入栈并搜索其左孩子 Push(S,p); num++; if (num>max) max=num; p=p->lchild; } Get(S,p); if (p->rchild&&p->rchild!=r) p=p->rchild; //如果右孩子存在并还没访问,则访问 else { Pop(S,p); num--; //出栈则层数减1 r=p; //r指向上一个访问节点 p=null; } } ruturn max; //返回最大高度 } |
2.方法思路:用层序遍历,这里需要记录每一层的第一个结点r,用于计算层数。时间为O(n),空间为结点最多的层*2。(自创)
代码如下(未测试):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | int TreeHeight(BiTree T){ if (!T) return 0; //树空,高度为0 InitQuece(Q); int max=0; //记录树高度 BiTree *p=T,*r=null; //r记录每一层的第一个结点 EnQuece(Q,p); while (!isEmpty(Q)){ //寻找下一层的第一个结点 int pd=0; //判定是否找到下一层的第一个结点 while (pd=0&&!isEmpty(Q)){ DeQuece(Q,p); if (p->lchild!=Null){ EnQuece(Q,p->lchild); r=p->lchild; pd=1; //已找到 } if (p->rchild!=Null){ EnQuece(Q,p->rchild); if (pd=0){ r=p->lchild; pd=1; //已找到 } } } if (!isEmpty(Q)) Get(Q,p); while (r!=p&&!isEmpty(Q)){ //处理该层剩余结点的孩子结点,使其入队 DeQuece(Q,p); if (p->lchild!=Null){ EnQuece(Q,p->lchild);} if (p->rchild!=Null){ EnQuece(Q,p->rchild);} } max++; //该层结点遍历完毕,层数+1 } return max; } |
3.方法思路:层次遍历+队列应用,设置变量level记录当前结点所在层数,设置变量last指向当前层最后结点,每次层次遍历出队时与last指针比较,若两者相等,那么层数加1,并让last指向下一层最右结点,至遍历完成。level的值即为二叉树的高度。时间为O(n),空间为O(n)。(王道书所述)
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | int Btdepth(BiTree T){ //采用层次遍历的非递归方法求解二叉树的高度 if (!T) return 0; //树空,高度为0 int front=-1,rear=-1; int last=0,level=0; //last指向下一层第一个结点的位置 BiTree Q[MaxSize]; //设置队列Q,元素是二叉树结点指针且容量足够 Q[++rear]=T; //根结点入队 BiTree p; while (front<rear){ //队不空,则循环 p=Q[++front]; //队列元素出队,则正在访问的结点 if (p->lchild) Q[++rear]=p->lchild; //左孩子入队 if (p->rchild) Q[++rear]=p->rchild; //右孩子入队 if (front==last){ //处理该层的最右结点 level++; //层数加1 last=rear; //last指向下层 } } return level; } |
4.递归方法
代码如下:
1 2 3 4 5 6 7 | int Btdepth(BiTree T){ if (T==NULL) return 0; ldep=Btdepth(T->lchild); //左子树高度 rdep=Btdepth(T->rchild); //右子树高度 if (ldep>rdep) return ldep+1; //树的高度为子树最大高度加根结点 else return rdep+1; } |